package com.dahaonetwork.smartfactory.zuul.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Gzip压缩过滤器，用于压缩资源
 */
public class CommGZIPFilter implements Filter {
	/** 日志记录 */
//	protected final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(this.getClass());
	private final Logger log = LoggerFactory.getLogger(this.getClass());  

	
	
	/** 初始化完成标识 */
	private boolean isInited = false;

	/** 排除的请求 */
	private List<String> excludes;

	/**
	 * 判断浏览器是否支持GZIP
	 * 
	 * @param request
	 * @return
	 */
	private static boolean isGZipEncoding(HttpServletRequest request) {
		boolean flag = false;
		String encoding = request.getHeader("Accept-Encoding");
		if (encoding == null) {
			return flag;
		}
		if (encoding.indexOf("gzip") != -1) {
			flag = true;
		}
		return flag;
	}

	/**
	 * @Title: isExcludes
	 * @Description: 是否包含过滤action
	 * @param
	 * @return boolean
	 * @throws
	 */
	private boolean isExcludes(HttpServletRequest request) {
		String url = request.getRequestURI();
		int index = url.lastIndexOf("/");
		String action = url.substring(index + 1, url.length());
		if (excludes.contains(action))
			return true;
		else
			return false;
	}

	/*
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletResponse resp = (HttpServletResponse) response;
		HttpServletRequest req = (HttpServletRequest) request;
		if (isGZipEncoding(req) && !isExcludes(req)) {
			CommonWrapper wrapper = new CommonWrapper(resp);
			chain.doFilter(request, wrapper);
			byte[] gzipData = gzip(wrapper.getResponseData());
			resp.addHeader("Content-Encoding", "gzip");
			resp.setContentLength(gzipData.length);
			ServletOutputStream output = response.getOutputStream();
			output.write(gzipData);
			output.flush();
		} else {
			chain.doFilter(request, response);
		}

	}

	/**
	 * 对data数据进行gzip压缩
	 * 
	 * @param data
	 * @return
	 */
	private byte[] gzip(byte[] data) {
		ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);
		GZIPOutputStream output = null;
		try {
			output = new GZIPOutputStream(byteOutput);
			output.write(data);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		} finally {
			try {
				if (output != null)
					output.close();
			} catch (IOException e) {
				log.error(e.getMessage(), e);
			}
		}
		return byteOutput.toByteArray();
	}

	/*
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig arg0) throws ServletException {
		if (!isInited) {

			String exclude = arg0.getInitParameter("exclude");
			if (exclude != null) {
				excludes = Arrays.asList(exclude.split(","));
			}
			// 初始化完成标识
			isInited = true;
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
		// TODO
	}
}
